package com.cong.modules.sys.controller;

import com.cong.common.constant.CoreConst;
import com.cong.common.util.PasswordHelper;
import com.cong.common.util.ServletUtils;
import com.cong.common.util.UUIDUtil;
import com.cong.common.vo.AjaxResultVo;
import com.cong.config.shiro.ShiroUtils;
import com.cong.modules.base.BaseController;
import com.cong.modules.sys.model.SysMenu;
import com.cong.modules.sys.model.SysUser;
import com.cong.modules.sys.service.MenuService;
import com.cong.modules.sys.service.UserService;
import com.google.code.kaptcha.Constants;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

@Controller
public class LoginController extends BaseController {

    @Resource
    private UserService userService;

    @Resource
    private MenuService menuService;

    /**
     * 首页请求返回菜单和用户信息
     *
     * @param modelMap 跳转参数实体
     * @return 返回系统首页
     */
    @RequestMapping("/index")
    public String index(ModelMap modelMap) {
        SysUser user = ShiroUtils.getUser();
        List<SysMenu> menus = menuService.listMenusByUser(user);
        modelMap.put("menus", menus);
        modelMap.put("user", user);
        return "index";
    }

    /**
     * 跳转注册页
     *
     * @return 返回系统注册页面
     */
    @GetMapping("/register")
    public String register() {
        return "register";
    }

    /**
     * 提交注册
     *
     * @param registerUser    注册用户
     * @param confirmPassword 确认密码
     * @param verification    验证码
     * @return 返回注册结果
     */
    @PostMapping("/register")
    @ResponseBody
    public AjaxResultVo register(SysUser registerUser, String confirmPassword, String verification) {
        try {
            // 判断验证码
            String rightCode = (String) ShiroUtils.getSessionAttribute(Constants.KAPTCHA_SESSION_KEY);
            if (!(StringUtils.isNotBlank(verification) && StringUtils.isNotBlank(rightCode)
                    && verification.equals(rightCode))) {
                return AjaxResultVo.error("验证码错误！");
            }
            String username = registerUser.getUsername();
            SysUser user = userService.getUserByUsername(username);
            if (null != user) {
                return AjaxResultVo.error("用户名已存在！");
            }
            // 判断两次输入密码是否相等
            String password = registerUser.getPassword();
            if (confirmPassword != null && password != null) {
                if (!confirmPassword.equals(password)) {
                    return AjaxResultVo.error("两次密码不一致！");
                }
            }
            registerUser.setUserId(Long.valueOf(UUIDUtil.getUniqueIdByUUId()));
            registerUser.setStatus(CoreConst.STATUS_VALID);
            Date date = new Date();
            registerUser.setCreateTime(date);
            registerUser.setUpdateTime(date);
            registerUser.setLastLoginTime(date);
            PasswordHelper.encryptPassword(registerUser);
            // 注册
            int registerResult = userService.register(registerUser);
            if (registerResult > 0) {
                return AjaxResultVo.success("注册成功！");
            } else {
                return AjaxResultVo.error("注册失败，请稍后再试！");
            }
        } catch (Exception e) {
            logger.error("用户注册异常 LoginController.register{}", e.getMessage());
            return AjaxResultVo.error("注册失败");
        }
    }

    /**
     * 登录页跳转 如果是Ajax请求，返回Json字符串
     *
     * @param request 请求实体
     * @param response 响应实体
     * @return 返回登录页面
     */
    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response) {
        if (ServletUtils.isAjaxRequest(request)) {
            String msg = "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}";
            return ServletUtils.renderString(response, msg);
        }
        return "login";
    }

    /**
     * 提交登录
     *
     * @param username 用户名
     * @param password 密码
     * @param validateCode 验证码
     * @param rememberMe 记住我
     * @return 返回登录结果
     */
    @PostMapping("/login")
    @ResponseBody
    public AjaxResultVo login(String username, String password, String validateCode, Boolean rememberMe) {
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
            String rightCode = (String) ShiroUtils.getSessionAttribute(Constants.KAPTCHA_SESSION_KEY);
            if (StringUtils.isBlank(rightCode)) {
                return AjaxResultVo.error("验证码失效！");
            }
            if (!(StringUtils.isNotBlank(validateCode) && validateCode.equals(rightCode))) {
                return AjaxResultVo.error("验证码错误！");
            }
            ShiroUtils.removeSessionAttribute(Constants.KAPTCHA_SESSION_KEY);
            try {
                ShiroUtils.getSubject().login(token);
            } catch (Exception e) {
                logger.error("token失效 LoginController.register{}", e.getMessage());
                token.clear();
                return AjaxResultVo.error("用户名或者密码错误！");
            }
            // 更新最后登录时间
            userService.updateLastLoginTimeByUser(ShiroUtils.getUser());
            return AjaxResultVo.success("登录成功！");
        } catch (Exception e) {
            logger.error("用户登录异常 LoginController.register{}", e.getMessage());
            return AjaxResultVo.error("登录失败");
        }
    }

    /**
     * 踢出系统
     */
    @GetMapping("/kickout")
    public String kickout() {
        return "kickout";
    }

}
